package com.smile.commons.page;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class MyBatisPlusPageConverter {

    /**
     * 转换单个对象 + 分页数据
     *
     * @param sourcePage 源分页对象
     * @param mapper 转换函数
     * @return 转换后的MyBatis-Plus分页对象
     */
    public static <S, T> Page<T> convertPage(IPage<S> sourcePage, Function<S, T> mapper) {
        if (sourcePage == null || sourcePage.getRecords() == null || sourcePage.getRecords().isEmpty()) {
            return emptyPage(sourcePage);
        }

        List<T> records = sourcePage.getRecords().stream()
                .map(mapper)
                .collect(Collectors.toList());

        return createPage(records, sourcePage);
    }

    /**
     * 使用BeanUtils复制属性
     *
     * @param sourcePage 源分页对象
     * @param targetClass 目标对象类型
     * @return 转换后的MyBatis-Plus分页对象
     */
    public static <S, T> Page<T> convertPage(IPage<S> sourcePage, Class<T> targetClass) {
        if (sourcePage == null || sourcePage.getRecords() == null || sourcePage.getRecords().isEmpty()) {
            return emptyPage(sourcePage);
        }

        List<T> records = sourcePage.getRecords().stream()
                .map(source -> convert(source, targetClass))
                .collect(Collectors.toList());

        return createPage(records, sourcePage);
    }

    /**
     * 树形结构分页转换方法
     */
    public static <S, T> Page<T> convertTreePage(
            IPage<S> sourcePage,
            Function<S, T> nodeConverter) {

        if (sourcePage == null || sourcePage.getRecords() == null) {
            return emptyPage(sourcePage);
        }

        // 转换整个树形结构
        List<T> convertedRecords = sourcePage.getRecords().stream()
                .map(nodeConverter)
                .collect(Collectors.toList());

        return createPage(convertedRecords, sourcePage);
    }

    /**
     * 转换记录列表但保留分页元数据
     *
     * @param sourcePage 源分页对象
     * @param records 已转换的记录列表
     * @return 包含新记录的分页对象
     */
    public static <S, T> Page<T> convertPage(IPage<S> sourcePage, List<T> records) {
        if (sourcePage == null) {
            return new Page<>();
        }

        Page<T> page = new Page<>();
        page.setRecords(records);
        page.setTotal(sourcePage.getTotal());
        page.setCurrent(sourcePage.getCurrent());
        page.setSize(sourcePage.getSize());
        return page;
    }

    /**
     * 创建带有元数据的空分页对象
     */
    private static <S, T> Page<T> emptyPage(IPage<S> sourcePage) {
        Page<T> page = new Page<>();
        if (sourcePage != null) {
            page.setTotal(sourcePage.getTotal());
            page.setCurrent(sourcePage.getCurrent());
            page.setSize(sourcePage.getSize());
        }
        return page;
    }

    /**
     * 创建带有元数据的分页对象
     */
    private static <T> Page<T> createPage(List<T> records, IPage<?> sourcePage) {
        Page<T> page = new Page<>();
        page.setRecords(records);
        page.setTotal(sourcePage.getTotal());
        page.setCurrent(sourcePage.getCurrent());
        page.setSize(sourcePage.getSize());
        page.setPages(sourcePage.getPages());
        return page;
    }

    /**
     * 使用BeanUtils复制单个对象属性
     */
    private static <T> T convert(Object source, Class<T> targetClass) {
        try {
            T target = targetClass.newInstance();
            BeanUtils.copyProperties(source, target);
            return target;
        } catch (Exception e) {
            throw new RuntimeException("对象转换失败", e);
        }
    }
}
